package cn.schoolwow.quickdao.module.database.dml.existQuery.flow.common;

import cn.schoolwow.quickdao.domain.entity.Entity;
import cn.schoolwow.quickdao.domain.entity.Property;
import cn.schoolwow.quickdao.domain.provider.DatabaseProvider;
import cn.schoolwow.quickdao.module.database.dml.common.domain.ManipulationOption;
import cn.schoolwow.quickdao.module.database.parent.domain.ResultSetConsumer;
import cn.schoolwow.quickdao.module.database.parent.flow.executor.ExecuteQueryConnectionFlow;
import cn.schoolwow.quickflow.domain.FlowContext;
import cn.schoolwow.quickflow.flow.BusinessFlow;
import cn.schoolwow.util.domain.query.instance.QueryInstance;

import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

public class GetCountByUniqueFieldNamesFlow implements BusinessFlow {
    @Override
    public void executeBusinessFlow(FlowContext flowContext) throws Exception {
        setStatement(flowContext);
        if(flowContext.containKey("instance")){
            setParameters(flowContext);
            executeStatement(flowContext);
        }else if(flowContext.containKey("instances")){
            Object[] instances = flowContext.checkData("instances", Object[].class);
            long instanceCount = 0;
            for(Object instance:instances){
                flowContext.putCurrentFlowData("instance", instance);
                setParameters(flowContext);
                executeStatement(flowContext);
                long count = flowContext.checkData("count", long.class);
                instanceCount += count;
            }
            flowContext.putData("count", instanceCount);
        }else{
            throw new IllegalArgumentException("上下文既没有instance属性也没有instances属性!");
        }
    }

    @Override
    public String name() {
        return "根据指定字段列表查询记录个数";
    }

    private void setStatement(FlowContext flowContext) {
        Entity entity = flowContext.checkData("entity", Entity.class);
        ManipulationOption manipulationOption = flowContext.checkInstanceData(ManipulationOption.class);
        DatabaseProvider databaseProvider = flowContext.checkInstanceData(DatabaseProvider.class);

        StringBuilder sqlBuilder = new StringBuilder();
        sqlBuilder.append("select count(1) from " + databaseProvider.escape(entity.tableName) + " where ");
        for (String uniqueFieldName: manipulationOption.uniqueFieldNames) {
            String column = entity.getColumnNameByFieldName(uniqueFieldName);
            sqlBuilder.append(databaseProvider.escape(column) + "= ? and ");
        }
        sqlBuilder.delete(sqlBuilder.length() - 5, sqlBuilder.length());
        flowContext.putTemporaryData("sql", sqlBuilder.toString());
    }

    private void setParameters(FlowContext flowContext) {
        Entity entity = flowContext.checkData("entity", Entity.class);
        Object instance = flowContext.checkData("instance");
        ManipulationOption manipulationOption = flowContext.checkInstanceData(ManipulationOption.class);

        List<Object> parameters = new ArrayList();
        for (String uniqueFieldName: manipulationOption.uniqueFieldNames) {
            Property property = entity.getPropertyByFieldNameOrColumnName(uniqueFieldName);
            Object value = QueryInstance.newQuery(instance)
                    .execute()
                    .getSingleFieldValue(property.name);
            parameters.add(value);
        }
        flowContext.putTemporaryData("parameters", parameters);
    }

    private void executeStatement(FlowContext flowContext){
        flowContext.startFlow(new ExecuteQueryConnectionFlow())
                .putTemporaryData("name", "根据指定唯一字段列表查询记录个数")
                .putReturnData("resultSetConsumer",new ResultSetConsumer() {
                    @Override
                    public void consumeResultSet(ResultSet resultSet) throws Exception {
                        if(resultSet.next()){
                            flowContext.putData("count", resultSet.getLong(1));
                        }
                    }
                })
                .execute();
    }

}
